﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace Panchina.Security.IKey1000
{
    [Guid("65E4D2C8-E449-4793-BC0F-4015819843D6")]
    [ProgId("Panchina.PanchinaIKeyX"),]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IPanchinaIKeyX))]
    [ComSourceInterfaces(typeof(IPanchinaIkeyEvent))]
    [ComVisible(true)]
    public class PanchinaIKeyX : IPanchinaIKeyX, IObjectSafety
    {
        #region IObjectSafety 成员

        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);
        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;

        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; break;
                default:
                    Rslt = E_NOINTERFACE; break;
            }
            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B"); switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true)) Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
                         (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE; break;
            }
            return Rslt;
        }

        #endregion

        #region 功能代码

        private IKeyManager ikey;
        public delegate void IKeyEventHanlder();
        public event IKeyEventHanlder Insert;
        public event IKeyEventHanlder Remove;

        public PanchinaIKeyX()
        {
            try
            {
                ikey = new IKeyManager();
                ikey.OnInsert += new IKEYCLIENTLib._IiKeyAuthEvents_InsertEventHandler(ikey_OnInsert);
                ikey.OnRemove += new IKEYCLIENTLib._IiKeyAuthEvents_RemoveEventHandler(ikey_OnRemove);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }

        void ikey_OnRemove()
        {
            //System.Windows.Forms.MessageBox.Show("remove from activex");
            if (Remove != null)
            {
                Remove();
            }

            //Array.ForEach<System.Diagnostics.Process>(
            //    System.Diagnostics.Process.GetProcessesByName("iexplore"),
            //    p => p.Kill());

        }

        void ikey_OnInsert()
        {
            //System.Windows.Forms.MessageBox.Show("insert from activex");
            if (Insert != null)
            {
                Insert();
            }
        }



        public void About()
        {
            System.Windows.Forms.MessageBox.Show("PanchinaIKeyX v1.0.0.0", "版本信息", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
        }

        /// <summary>
        /// 获取KEY序列号
        /// </summary>
        /// <param name="nextDevice">是否为第二个设备</param>
        /// <returns>KEY序列号</returns>
        public string GetKeySN(bool nextDevice)
        {
            string sn = "";
            bool open = false;
            try
            {
                if (nextDevice)
                {
                    open = ikey.OpenNextDevice();
                }
                else
                {
                    open = ikey.OpenDevice();
                }

                if (open)
                {

                    sn = ikey.GetSN();

                }
            }
            catch (Exception ex)
            {
                sn = "";
            }
            finally
            {
                ikey.CloseDevice();
            }
            return sn;
        }

        /// <summary>
        /// 获取用户姓名
        /// </summary>
        /// <param name="nextDevice">是否为第二个设备</param>
        /// <returns>用户姓名</returns>
        public string GetUserName(bool nextDevice)
        {
            string name = "";
            bool open = false;
            try
            {
                if (nextDevice)
                {
                    open = ikey.OpenNextDevice();
                }
                else
                {
                    open = ikey.OpenDevice();
                }

                if (open)
                {

                    name = ikey.GetFriendlyName();

                }
            }
            catch (Exception ex)
            {
                name = "";
            }
            finally
            {
                ikey.CloseDevice();
            }

            return name.Replace("\0", "");
        }

        /// <summary>
        /// 读取用户ID
        /// </summary>
        /// <param name="nextDevice">是否为第二个设备</param>
        /// <returns>用户ID</returns>
        public string GetUserId(bool nextDevice)
        {
            string id = "";
            bool open = false;
            try
            {
                if (nextDevice)
                {
                    open = ikey.OpenNextDevice();
                }
                else
                {
                    open = ikey.OpenDevice();
                }

                if (open)
                {

                    IKeyapi.AccessType access = new IKeyapi.AccessType();
                    access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_NONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                    if (ikey.ChangeRootDir())
                    {
                        if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserId), IKeyapi.IKEY_FILETYPE_DATA, access))
                        {
                            id = ikey.ReadData(IKeyapi.fileInfo.lFileSize);
                        }
                    }

                    ikey.CloseFile();

                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("打开设备失败");
                }
            }
            catch (Exception ex)
            {
                id = "";
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
            finally
            {
                ikey.CloseDevice();
            }

            return id;
        }

        /// <summary>
        /// 读取用户Token
        /// </summary>
        /// <returns>存储在IKEY中的用户当前Token</returns>
        public string GetUserToken()
        {
            string token = "";

            bool open = false;

            try
            {
                open = ikey.OpenDevice();

                if (open)
                {

                    IKeyapi.AccessType access = new IKeyapi.AccessType();
                    access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_NONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                    if (ikey.ChangeRootDir())
                    {
                        if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserToken), IKeyapi.IKEY_FILETYPE_DATA, access))
                        {
                            token = ikey.ReadData(IKeyapi.fileInfo.lFileSize);
                        }
                    }

                    ikey.CloseFile();

                }
            }
            catch (Exception ex)
            {
                token = "";
            }
            finally
            {
                ikey.CloseDevice();
            }

            return token;
        }

        /// <summary>
        /// 读取用户IP
        /// </summary>
        /// <returns>存储在IKEY中的用户当前IP</returns>
        public string GetUserIP()
        {
            string ip = "";

            bool open = false;
            try
            {
                open = ikey.OpenDevice();

                if (open)
                {

                    IKeyapi.AccessType access = new IKeyapi.AccessType();
                    access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_NONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                    if (ikey.ChangeRootDir())
                    {
                        if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserIP), IKeyapi.IKEY_FILETYPE_DATA, access))
                        {
                            ip = ikey.ReadData(IKeyapi.fileInfo.lFileSize);
                        }
                    }

                    ikey.CloseFile();

                }
            }
            catch (Exception ex)
            {
                ip = "";
            }
            finally
            {
                ikey.CloseDevice();
            }
            return ip;
        }

        /// <summary>
        /// 创建管理员KEY
        /// </summary>
        /// <param name="userid">管理员ID</param>
        /// <param name="username">管理员姓名 </param>
        /// <returns>结果</returns>
        public string CreateAdminKey(string userid, string username)
        {
            string result = "";

            if (ikey.OpenDevice())
            {
                try
                {
                    IKeyapi.AccessType access = new IKeyapi.AccessType();
                    access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                    if (ikey.ChangeRootDir())
                    {
                        if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserId), IKeyapi.IKEY_FILETYPE_DATA, access))
                        {
                            ikey.CloseFile();
                            ikey.DeleteFile(Convert.ToInt32(IKeyFileId.UserId));
                        }

                        ikey.CreateFile(0, Convert.ToInt32(IKeyFileId.UserId), 32, IKeyapi.IKEY_FILETYPE_DATA, access);

                        ikey.WriteData(userid);
                        ikey.CloseFile();
                    }

                    try
                    {
                        ikey.SetFriendlyName(username);
                    }
                    catch (Exception ex)
                    {
                        result = ikey.KeyExceptionStatus(ex.Message).Message;
                    }
                }
                catch (Exception ex)
                {
                    result = ikey.KeyExceptionStatus(ex.Message).Message;
                }
            }
            else
            {
                result = "未找到需要创建的密钥设备！";
            }

            ikey.CloseDevice();

            return result;
        }

        /// <summary>
        /// 创建用户KEY，创建时需先插入管理员KEY
        /// </summary>
        /// <param name="userid">用户ID</param>
        /// <param name="username">用户名</param>
        /// <returns>结果</returns>
        public string CreateUserKey(string userid, string username)
        {
            string result = "";

            if (ikey.OpenNextDevice())
            {
                try
                {
                    IKeyapi.AccessType access = new IKeyapi.AccessType();
                    access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;
                    access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                    if (ikey.ChangeRootDir())
                    {
                        if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserId), IKeyapi.IKEY_FILETYPE_DATA, access))
                        {
                            ikey.CloseFile();
                            ikey.DeleteFile(Convert.ToInt32(IKeyFileId.UserId));
                        }

                        ikey.CreateFile(0, Convert.ToInt32(IKeyFileId.UserId), 32, IKeyapi.IKEY_FILETYPE_DATA, access);

                        ikey.WriteData(userid);
                        ikey.CloseFile();
                    }

                    try
                    {
                        ikey.SetFriendlyName(username);
                    }
                    catch (Exception ex)
                    {
                        result = ikey.KeyExceptionStatus(ex.Message).Message;
                    }
                }
                catch (Exception ex)
                {
                    result = ikey.KeyExceptionStatus(ex.Message).Message;
                }
            }
            else
            {
                result = "未找到需要创建的密钥设备！";
            }

            ikey.CloseDevice();

            return result;
        }

        /// <summary>
        /// 删除管理员KEY
        /// </summary>
        /// <returns>结果</returns>
        public string DeleteAdminKey()
        {
            string result = "";

            if (ikey.OpenDevice())
            {
                try
                {
                    ikey.DeleteFile(Convert.ToInt32(IKeyFileId.UserId));

                    try
                    {
                        ikey.SetFriendlyName("");
                    }
                    catch (Exception ex)
                    {
                        result = ikey.KeyExceptionStatus(ex.Message).Message;
                    }
                }
                catch (Exception ex)
                {
                    result = ikey.KeyExceptionStatus(ex.Message).Message;
                }
            }
            else
            {
                result = "未找到需要删除的密钥设备！";
            }

            ikey.CloseDevice();

            return result;
        }

        /// <summary>
        /// 删除用户KEY
        /// </summary>
        /// <returns>结果</returns>
        public string DeleteUserKey()
        {
            string result = "";

            if (ikey.OpenNextDevice())
            {
                try
                {
                    ikey.DeleteFile(Convert.ToInt32(IKeyFileId.UserId));

                    try
                    {
                        ikey.SetFriendlyName("");
                    }
                    catch (Exception ex)
                    {
                        result = ikey.KeyExceptionStatus(ex.Message).Message;
                    }
                }
                catch (Exception ex)
                {
                    result = ikey.KeyExceptionStatus(ex.Message).Message;
                }
            }
            else
            {
                result = "未找到需要删除的密钥设备！";
            }

            ikey.CloseDevice();

            return result;
        }

        /// <summary>
        /// 写入当前用户Token
        /// </summary>
        /// <param name="token">当前用户本次会话的token值</param>
        /// <returns>结果</returns>
        public string WriteUserToken(string token)
        {
            string result = "";

            if (ikey.OpenDevice())
            {
                IKeyapi.AccessType access = new IKeyapi.AccessType();
                access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                access.Write = IKeyapi.IKEY_ACCESS_ANYONE;
                access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                if (ikey.ChangeRootDir())
                {
                    if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserToken), IKeyapi.IKEY_FILETYPE_DATA, access))
                    {
                        ikey.CloseFile();
                        ikey.DeleteFile(Convert.ToInt32(IKeyFileId.UserToken));
                    }

                    ikey.CreateFile(0, Convert.ToInt32(IKeyFileId.UserToken), 36, IKeyapi.IKEY_FILETYPE_DATA, access);

                    ikey.WriteData(token);
                    ikey.CloseFile();
                }
            }

            ikey.CloseDevice();

            return result;
        }

        /// <summary>
        /// 写入当前用户ip
        /// </summary>
        /// <param name="token">当前用户本次会话的ip值</param>
        /// <returns>结果</returns>
        public string WriteUserIP(string ip)
        {
            string result = "";

            if (ikey.OpenDevice())
            {
                IKeyapi.AccessType access = new IKeyapi.AccessType();
                access.Read = IKeyapi.IKEY_ACCESS_ANYONE;
                access.Write = IKeyapi.IKEY_ACCESS_ANYONE;
                access.Write = IKeyapi.IKEY_ACCESS_ANYONE;

                if (ikey.ChangeRootDir())
                {
                    if (ikey.OpenFile(Convert.ToInt32(IKeyFileId.UserIP), IKeyapi.IKEY_FILETYPE_DATA, access))
                    {
                        ikey.CloseFile();
                        ikey.DeleteFile(Convert.ToInt32(IKeyFileId.UserIP));
                    }

                    ikey.CreateFile(0, Convert.ToInt32(IKeyFileId.UserIP), 15, IKeyapi.IKEY_FILETYPE_DATA, access);

                    ikey.WriteData(ip);
                    ikey.CloseFile();
                }
            }

            ikey.CloseDevice();

            return result;
        }
        #endregion
    }
}

public enum IKeyFileId
{
    UserId = 0,
    UserToken = 2,
    UserIP = 3,
}